package com.fofia.iotweb.web.dbdomain.services.admin;


import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.fofia.iotweb.Contants.DataStatusEnum;
import com.fofia.iotweb.common.IdHelper;
import com.fofia.iotweb.framework.dto.ZtreeDto;
import com.fofia.iotweb.web.dbdomain.mappers.admin.SysMenuMapper;
import com.fofia.iotweb.web.dbdomain.mappers.admin.SysOperateMapper;
import com.fofia.iotweb.web.dbdomain.mappers.admin.SysRoleAuthorizeMapper;
import com.fofia.iotweb.web.dbdomain.mappers.admin.SysRoleMapper;
import com.fofia.iotweb.web.dbdomain.models.admin.SysMenu;
import com.fofia.iotweb.web.dbdomain.models.admin.SysOperate;
import com.fofia.iotweb.web.dbdomain.models.admin.SysRole;
import com.fofia.iotweb.web.dbdomain.models.admin.SysRoleAuthorize;
import com.fofia.iotweb.web.dto.DataTableDto;
import com.fofia.iotweb.web.dto.KeyValueInt64Dto;
import com.fofia.iotweb.web.dto.LoginUserDto;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;

import java.util.*;

@Component
public class SysRoleService {

    @Inject("db")
    private SysRoleMapper roleMapper;
    @Inject("db")
    private SysMenuMapper menuMapper;

    @Inject("db")
    private SysOperateMapper operateMapper;

    @Inject("db")
    private SysRoleAuthorizeMapper roleAuthorizeMapper;
    public DataTableDto getPageList(int page, int psize, String roleName){


        QueryWrapper queryWrapper=QueryWrapper.create();
        if(!StrUtil.isEmpty(roleName)){
            queryWrapper.where(SysRole::getRoleName).eq(roleName);
        }

        queryWrapper.orderBy(SysRole::getId).asc();

        Page<SysRole> records=roleMapper.paginate(page,psize,queryWrapper);
        var list=records.getRecords();
        DataTableDto  dto=new DataTableDto();
        dto.setRows(list);
        dto.setTotal(records.getTotalRow());
        dto.setPageNumber(page);
        dto.setPageSize(psize);

        return dto;
    }


    public SysRole getModel(long id){
        QueryWrapper query= QueryWrapper.create()
                .where(SysRole::getId).eq(id)

                .limit(1);
        SysRole role= roleMapper.selectOneByQuery(query);
       return role;
    }

    /**
     * 保存数据
     * @param role
     * @param loginUserDto
     */
    public void save(SysRole role, LoginUserDto loginUserDto){
        if(StrUtil.isEmpty(role.getRoleCode())){
            role.setRoleCode("");
        }

        if(role.getId()==0){
            role.setId(IdHelper.nextId());
            role.setCreateTime(new Date());
            role.setCreatePerson(loginUserDto.getLoginName());
            roleMapper.insert(role);
        }else{
            roleMapper.update(role);
        }

    }

    public void removeAll(String ids){

        List<Long> idArray = Arrays.asList(Convert.toLongArray(ids)) ;

        roleMapper.deleteBatchByIds(idArray);
    }


    /**
     *
     * @author yushuo
     * @description //角色下拉列表
     * @date 12:06 2021/2/2
     * @param []
     * @return java.util.List<com.easycms.framework.domain.KeyValueInt64Dto>
     **/
    public List<KeyValueInt64Dto> getRoles(){
        QueryWrapper query=QueryWrapper.create()
                       .select(SysRole::getId, SysRole::getRoleName)
                .where(SysRole::getRoleSuper).eq(DataStatusEnum.NOT_SUPER.getCode())
                .where(SysRole::getRoleStatus).eq(DataStatusEnum.ENABLE.getCode())
                .orderBy(SysRole::getRoleSort).asc();

        List<KeyValueInt64Dto> data=new ArrayList<>();
        List<SysRole> roles=roleMapper.selectListByQuery(query);
        roles.forEach(r->{
            KeyValueInt64Dto dto=new KeyValueInt64Dto();
            dto.setId(r.getId());
            dto.setName(r.getRoleName());
            data.add(dto);
        });

        return data;
    }

    /// <summary>
    /// 设置角色权限，获取对应角色权限
    /// </summary>
    /// <param name="roleid"></param>
    /// <returns></returns>
    public List<ZtreeDto> getRoleMenuList(long roleid)
    {
        List<ZtreeDto> roleMenuList=new ArrayList<>();
        //获取菜单列表
        QueryWrapper query=QueryWrapper.create()
                .select(SysMenu::getId, SysMenu::getMenuName,SysMenu::getParentId)
                .orderBy(SysMenu::getMenuSort).asc();

        List<SysMenu> menuList=menuMapper.selectListByQuery(query);
        if(menuList.isEmpty()){
            return roleMenuList;
        }

        //获取按钮列表
        List<Long> menuIds=menuList.stream().map(s->s.getId()).toList();
        QueryWrapper operateQuery=QueryWrapper.create()
                .in(SysOperate::getMenuId,menuIds);
        List<SysOperate> operateList=operateMapper.selectListByQuery(operateQuery);

        //获取角色权限
        QueryWrapper permsQuery=QueryWrapper.create()
                      .eq(SysRoleAuthorize::getRoleId,roleid);
        List<SysRoleAuthorize> roleAuthorizeList=roleAuthorizeMapper.selectListByQuery(permsQuery);

        int permsCount = roleAuthorizeList.size();
        //设置菜单选中
        for (SysMenu menu:menuList){
            ZtreeDto ztreeDto=new ZtreeDto();
            ztreeDto.setId(menu.getId().toString());
            ztreeDto.setPId(menu.getParentId().toString());
            ztreeDto.setName(menu.getMenuName());
            if(permsCount>0){
                long menuId=menu.getId();
                long menuPId=menu.getParentId();

                Optional<SysRoleAuthorize> hasPerms=  roleAuthorizeList.stream()
                        .filter(s ->s.getMenuId()==menuId )
                        .findFirst();
                if(hasPerms.isPresent()){
                    ztreeDto.setCheckstate(true);
                }

            }
            roleMenuList.add(ztreeDto);
        }

        //设置按钮选中
        for (SysOperate operate:operateList){
            ZtreeDto ztreeDto=new ZtreeDto();
            ztreeDto.setId(operate.getId().toString());
            ztreeDto.setPId(operate.getMenuId().toString());
            ztreeDto.setName(operate.getFuncTitle());
            if(permsCount>0){
                long menuId=operate.getId();
                long menuPId=operate.getMenuId();
                Optional<SysRoleAuthorize> hasPerms=  roleAuthorizeList.stream()
                        .filter(s ->s.getMenuId()==menuId)//&&s.getMenuPid()==menuPId
                        .findFirst();
                if(hasPerms.isPresent()){
                    ztreeDto.setCheckstate(true);
                }
            }
            roleMenuList.add(ztreeDto);
        }

        return roleMenuList;
    }

    /**
     *
     * @author yushuo
     * @description //TODO
     * @date 15:20 2021/2/22
     * @param [roleId, permissions]
     * @return void
     **/

    public void savePermissions(Long roleId,List<ZtreeDto> permissions,String accountName){

        QueryWrapper query=QueryWrapper.create();
        query.eq(SysRoleAuthorize::getRoleId,roleId);
        roleAuthorizeMapper.deleteByQuery(query);

        if(!permissions.isEmpty()){
            Date now= DateUtil.date();
            List<SysRoleAuthorize> roleAuthorizeList=new ArrayList<>();
            for (ZtreeDto ztreeDto:permissions){

                SysRoleAuthorize model=new SysRoleAuthorize();
                model.setId(IdHelper.nextId());
                model.setRoleId(roleId);
                model.setMenuId(Convert.toLong(ztreeDto.getId()));
                model.setMenuPid(Convert.toLong(ztreeDto.getPId()));
                model.setCreateTime(now);
                model.setCreatePerson(accountName);
                roleAuthorizeList.add(model);
            }

            roleAuthorizeMapper.insertBatch(roleAuthorizeList);
        }

        //每次变更权限后移除缓存
       // PermissionCache.removeRolePermission(roleId);
    }

}
